:- module(ic_gap_sbds).
:- export first_solution_body / 2.
:- export all_solutions_body / 3.
:- export all_solutions_body / 2.
:- export sbds_initialise_set_body / 6.
:- export sbds_initialise_body / 6.
:- export unify_sbds / 2.
:- export print_sbds / 2.
:- export all_solutions / 2.
:- export all_solutions / 1.
:- export first_solution / 1.
:- export is_sbds_var / 1.
:- export sbds_labeling / 1.
:- export sbds_indomain / 1.
:- export sbds_record / 3.
:- export sbds_try_set / 4.
:- export sbds_try_set / 3.
:- export sbds_try / 3.
:- export sbds_try / 2.
:- export sbds_initialise_set / 5.
:- export sbds_initialise / 5.
:- comment(summary, "GAP-based Symmetry Breaking During Search (SBDS)").
:- comment(desc, html("   This library provides a GAP-based Symmetry Breaking During Search (SBDS)\n   library, as described in:<P>\n\n   Ian P. Gent, Warwick Harvey and Tom Kelsey.  \"Groups and Constraints:\n   Symmetry Breaking during Search.\".  In P. Van Hentenryck, editor,\n   <EM>Proceedings of the Eighth International Conference on Principles and\n   Practice of Constraint Programming - CP 2002</EM>, LNCS 2470, pages\n   415-430.  Springer-Verlag, 2002.<P>\n\n   It has been enhanced by (amongst other things) being integrated with the\n   symmetry expression library described in:<P>\n\n   Warwick Harvey, Tom Kelsey and Karen Petrie.  \"Symmetry Group Expression\n   for CSPs.\"  In Barbara Smith et al., editors, <EM>Proceedings of\n   SymCon'03: Third International Workshop on Symmetry in Constraint\n   Satisfaction Problems, a workshop of CP 2003</EM>, pages 86-96.\n   September, 2003.<P>\n\n   This library is still being developed and is expected to evolve.\n   Feedback, suggestions, problem reports, etc. welcome.<P>\n\n   Please note that this library currently does not work on Windows machines\n   due to its dependence on the GAP interface library.<P>\n")).
:- comment(see_also, [library(sym_expr), library(gap)]).
:- comment(author, "Warwick Harvey, Ian Gent (and probably others...)").
:- comment(status, evolving).
:- comment(all_solutions / 1, [summary : "Find all solutions to the given goal", args : ["Goal" : "The goal to execute"], amode : all_solutions(+), see_also : [all_solutions / 2, first_solution / 1], desc : html("   Finds all solutions for the goal Goal, and prints various statistics\n   about the computation (CPU time taken, number of backtracks, etc.).\n")]).
:- comment(all_solutions / 2, [summary : "Find all solutions to the given goal", args : ["Goal" : "The goal to execute", "NSols" : "The number of solutions found"], amode : all_solutions(+, ?), see_also : [all_solutions / 1, first_solution / 1], desc : html("   Finds all solutions for the goal Goal, and prints various statistics\n   about the computation (CPU time taken, number of backtracks, etc.).  The\n   number of solutions found is unified with NSols.\n")]).
:- comment(first_solution / 1, [summary : "Find the first solution to the given goal", args : ["Goal" : "The goal to execute"], amode : first_solution(+), see_also : [all_solutions / 1, all_solutions / 2], desc : html("   Finds the first solution for the goal Goal, and prints various statistics\n   about the computation (CPU time taken, number of backtracks, etc.).\n")]).
:- comment(is_sbds_var / 1, [summary : "Checks whether a variable is an SBDS variable", args : ["Var" : "The variable to check"], amode : is_sbds_var(?), desc : html("   Succeeds iff Var is an SBDS variable (i.e. has been initialised through\n   a call to sbds_initialise/5).\n")]).
:- comment(sbds_indomain / 1, [summary : "Instantiate an integer SBDS variable to an element of its domain", args : ["Var" : "The (integer) SBDS variable to instantiate, or an integer"], amode : sbds_indomain(?), see_also : [indomain / 1, sbds_try / 2, sbds_labeling / 1], desc : html("   Like indomain/1, but uses sbds_try/2 to do the instantiation so that the\n   SBDS algorithms are invoked appropriately.\n")]).
:- comment(sbds_initialise / 5, [summary : "Initialises the data structures required by the SBDS algorithm", args : ["Array" : "Array of (integer) decision variables", "VarDimNames" : "Names for the dimensions of Array", "ValueDimSpec" : "Name of the value dimension and its range", "SymSpecs" : "List of symmetry specifiers", "Options" : "List of extra options"], amode : sbds_initialise(+, ++, ++, +, +), see_also : [sbds_initialise_set / 5, construct_group / 8, sbds_try / 2, sbds_try / 3], desc : html("   Sets up the data structures required to perform an SBDS search.  Array is\n   an array containing the (integer) search variables, SymSpecs defines the\n   symmetries of the problem, with VarDimNames and ValueDimSpec providing\n   some extra required information; these four arguments are the same as the\n   first four arguments of construct_group/8: please see the documentation\n   for that predicate for a complete description of these arguments and\n   details of the supported symmetry specifiers.<P>\n\n   Options is a list of options which modify the way the search progresses.\n   Currently no options are supported.<P>\n\n   During search, use sbds_try/2 or sbds_try/3 on variables from Array when\n   making search decisions.\n")]).
:- comment(sbds_initialise_set / 5, [summary : "Initialises the data structures required by the SBDS algorithm (set version)", args : ["Array" : "Array of integer set decision variables", "VarDimNames" : "Names for the dimensions of Array", "ValueDimSpec" : "Name of the value dimension and its range", "SymSpecs" : "List of symmetry specifiers", "Options" : "List of extra options"], amode : sbds_initialise_set(+, ++, ++, +, +), see_also : [sbds_initialise / 5, sbds_try_set / 3, sbds_try_set / 4], desc : html("   Like sbds_initialise/5, but for set models (i.e. Array should be an array\n   of integer set variables).  The \"value\" dimension is the values that can \n   appear in the set, so that, for example, a range of 1..5 indicates that\n   the upper bound of the set variables is [1,2,3,4,5].<P>\n\n   See the documentation for sbds_initialise/5 for more details.\n\n   During search, use sbds_try_set/3 or sbds_try_set/4 on variables from\n   Array when making search decisions.\n")]).
:- comment(sbds_labeling / 1, [summary : "Instantiate all integer SBDS variables in a list to elements of their domains", args : ["List" : "A list of integer SBDS variables or integers"], amode : sbds_labeling(?), see_also : [labeling / 1, sbds_indomain / 1], desc : html("   Like labeling/1, but uses sbds_indomain/1 to do the instantiation so that\n   the SBDS algorithms are invoked appropriately.\n")]).
:- comment(sbds_try / 2, [summary : "Try assigning a value to an SBDS search variable", args : ["Var" : "The variable to use", "Value" : "The value to try"], amode : sbds_try(+, ++), see_also : [sbds_initialise / 5, sbds_try / 3], desc : html("   Make an SBDS search choice.  Specifically, try assigning the (integer)\n   value Value to the variable Var; on backtracking exclude the value Value\n   from the domain of Var.<P>\n\n   Var should be an element of an array previously initialised using\n   sbds_initialise/5.<P>\n\n   Use sbds_try/3 if you wish to know which is the currently successful\n   branch (Var #= Value or Var #\\= Value).\n")]).
:- comment(sbds_try / 3, [summary : "Try assigning a value to an SBDS search variable", args : ["Var" : "The variable to use", "Value" : "The value to try", "Success" : "Whether the assignment succeeded or not"], amode : sbds_try(+, ++, ?), see_also : [sbds_initialise / 5, sbds_try / 2], desc : html("   Like sbds_try/2, but assign 1 to Success if we have set Var #= Value, and\n   assign 0 if we have set Var #\\= Value (effectively, Success reflects the\n   truth of Var #= Value when the predicate succeeds).<P>\n\n   See the documentation for sbds_try/2 for more details.\n")]).
:- comment(sbds_try_set / 3, [summary : "Try adding/excluding a value to/from an SBDS set search variable", args : ["Var" : "The set variable to use", "Value" : "The value to try", "Bool" : "Whether to add or exclude the value first"], amode : sbds_try_set(+, ++, ++), see_also : [sbds_initialise_set / 5, sbds_try_set / 4, sbds_try / 2], desc : html("   Make an SBDS (set) search choice.  Specifically, if Bool is 1, try adding\n   the (integer) value Value to the (set) variable Var; on backtracking\n   exclude it.  If Bool is 0, try excluding Value first and try adding it on\n   backtracking.<P>\n\n   Var should be an element of an array previously initialised using\n   sbds_initialise_set/5.<P>\n\n   Use sbds_try_set/4 if you wish to know which is the currently successful\n   branch (Value in Var or Value notin Var).\n")]).
:- comment(sbds_try_set / 4, [summary : "Try adding/excluding a value to/from an SBDS set search variable", args : ["Var" : "The set variable to use", "Value" : "The value to try", "Bool" : "Whether to add or exclude the value first", "Success" : "Whether the assignment succeeded or not"], amode : sbds_try_set(+, ++, ++, ?), see_also : [sbds_initialise_set / 5, sbds_try_set / 3, sbds_try / 3], desc : html("   Like sbds_try_set/3, but assign 1 to Success if we have Value in Var, and\n   assign 0 if we have Value notin Var (effectively, Success reflects the\n   truth of Value in Var when the predicate succeeds).<P>\n\n   See the documentation for sbds_try_set/3 for more details.\n")]).
:- comment(first_solution_body / 2, hidden).
:- comment(all_solutions_body / 3, hidden).
:- comment(all_solutions_body / 2, hidden).
:- comment(sbds_initialise_set_body / 6, hidden).
:- comment(sbds_initialise_body / 6, hidden).
